package chexuan.game.service.event;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import chexuan.game.constant.event.EnumEventType;
import chexuan.game.interfaces.common.InterfaceEventListener;
import chexuan.game.interfaces.event.EventHandler;
import chexuan.game.interfaces.service.InterfaceEventService;
import chexuan.game.util.SystemUtil;

public class EventHandlerProxy implements InterfaceEventListener {

	private static Map<Object, EventHandlerProxy> REGISTRY = new HashMap<Object, EventHandlerProxy>();
	private final Object proxyObject;
	private final Map<EnumEventType, Method> methodMap;

	private EventHandlerProxy(Object proxyObject) {
		this.proxyObject = proxyObject;
		this.methodMap = new HashMap<EnumEventType, Method>();
		for (Method m : proxyObject.getClass().getDeclaredMethods()) {
			if (m.isAnnotationPresent(EventHandler.class)) {
				EventHandler handler = m.getAnnotation(EventHandler.class);
				this.methodMap.put(handler.value(), m);
				if (!m.isAccessible()) {
					m.setAccessible(true);
				}
			}
		}
	}

	@Override
	public void onEvent(Event event) {
		Method m = methodMap.get(event.getType());
		if (m != null) {
			try {
				m.invoke(proxyObject, event);
			} catch (Throwable e) {
			}
		} else {
		}
	}

	public void register() {
		InterfaceEventService eventHub = SystemUtil.getEventService();
		eventHub.register(
				this.methodMap.keySet().toArray(new EnumEventType[0]), this);
	}

	public void unregister() {
		InterfaceEventService eventHub = SystemUtil.getEventService();
		eventHub.unregister(this);
	}

	public static void register(Object proxyObject) {
		if (!REGISTRY.containsKey(proxyObject)) {
			EventHandlerProxy proxy = new EventHandlerProxy(proxyObject);
			proxy.register();
			REGISTRY.put(proxyObject, proxy);
		}
	}

	public static void unregister(Object proxyObject) {
		EventHandlerProxy proxy = REGISTRY.get(proxyObject);
		if (proxy != null) {
			proxy.unregister();
		} else {
		}
	}

}
